iT邦幫忙

2026 iThome 鐵人賽

DAY 6
0
AI Security

一個 Agent 我查不動,一個我改得動:內部威脅偵測的 30 天系列 第 6

欄位的三層境界,與Jev 模型到底能補上哪一欄

  • 分享至 

  • xImage
  •  

昨天結尾我留了兩個承諾:把軌跡的欄位表定下來,還有給你 Jev 的數字,包含它答錯的那幾題

兩個都做了。欄位表定出來了,但結論跟我原本想的不一樣——我以為模型會補上我填不滿的那一欄,結果它補的是另一欄。至於「答錯的那幾題」,我本來以為會是一句「錯了六題」,寫到一半才發現這句話講不出口,因為我沒辦法乾淨地說它錯了。

由於內容實在太豐富,我決定把這段探索拆成四篇。今天,我們先把地基打好:定出欄位的三層境界,並看看回傳機率的模型(Jev)到底能幫我們補上哪一欄。

前五天怎麼走到今天

先用一張圖,把前五天撞過的牆串起來:

https://ithelp.ithome.com.tw/upload/images/20260920/20183541C9jry6PjEu.png

這五天不是一路「加功能」,而是一路排除更早的失敗:

  • Day 1–2 先確認紀錄器和警報器真的有在工作。連內容都沒讀到,後面的分析全是假象。
  • Day 3–4 再問紀錄的欄位夠不夠、能不能分辨改動的性質。只有工具名,不等於知道它做了什麼。
  • Day 5 終於拿到完整內容、重建出版本鏈,接著又被換行符打破雜湊,才補上「證據能不能對回磁碟」這一關。

走到這裡,問題才縮小成 Day 6 的樣子:內容已經記到了,也能驗證來源;接下來怎麼判斷這次改動的性質?確定性規則判不出來的地方,模型能補上多少?

有了這張路線圖,再看今天兩組資料的機率分佈:

【改動邏輯組 (n=64)】
0.0 - 0.1 █ 2
0.1 - 0.2 ▏ 1
0.2 - 0.3 █ 2
0.3 - 0.4 █▏ 3
0.4 - 0.5 ▏ 1
0.5 - 0.6  0
0.6 - 0.7 ▏ 1
0.7 - 0.8 █ 2
0.8 - 0.9 █▏ 3
0.9 - 1.0 ██████████████████████████████████████████████ 48

【憑證偵測組 (n=75)】
0.0 - 0.1 ███████████████████████████████████████████████████████████ 59
0.1 - 0.2  0
0.2 - 0.3  0
0.3 - 0.4  0
0.4 - 0.5  0
0.5 - 0.6  0
0.6 - 0.7 ▍ 4
0.7 - 0.8 ▏ 2
0.8 - 0.9  0
0.9 - 1.0 ██████████ 10

(註:這張極端的雙峰分佈圖,展示了絕大多數數據都擠在 0.0-0.1 與 0.9-1.0 兩端,中間幾乎是空的。這意味著它無法提供平滑的風險分數,要做排序必須靠其他訊號。)


先把欄位表定下來

這五天我一直在查「它做了什麼」。今天把要記的欄位攤開來,才看清楚問題在哪。欄位其實分三層,而我一直把它們混在一起講:

欄位 從哪裡來 記得到嗎
第一層:它動了什麼 時間、工具名、檔案路徑、寫入內容、內容雜湊 hook payload 直接給 ✅ 記得到
第二層:它動的是什麼性質 改的是測試還是正式碼、動到執行邏輯還是只動註解、有沒有移除斷言、有沒有碰到憑證 要自己分析內容 ⚠️ 要花力氣,而且有上限
第三層:它憑什麼那樣動 依據哪句話、讀了哪份檔、為什麼選這個做法 —— ❌ 沒有來源

第三層不是「難記」,是根本沒有資料來源。

前兩層的欄位都能從 hook 拿到的內容推出來,第三層要的東西從來沒有流經 hook。這件事我前五天一直沒講清楚,因為我把它跟第二層的「要花力氣」混成一句「查不動」。

分開之後,今天要驗的題目就明確了:Jev 補得上第二層,還是第三層?


我問了兩個問題,一共 139 次

Jev(TypeSafe 的模型)不生成文字,只回一個 0 到 1 的機率。為了測試它,我準備了兩組真實歷史數據,一共問了 139 次:

  • 「這筆紀錄裡有沒有憑證?」(75 次)。基準是那批紀錄裡確實含不含某一把已經作廢的 key。
  • 「這次改動有沒有動到執行邏輯?」(64 次)。基準是比對改動前後的 ast.dump()

兩組都有標準答案,所以算得出它對錯。這是重點:沒有標準答案的時候,你沒有資格評估一個回機率的偵測器。 今天能做這件事,是因為前五天我們先把確定性的基準做出來了。

然而,當我把這 139 次的機率分佈畫出來時,我看到了上面那張極端的雙峰分佈圖

這張圖告訴我們兩件事:

  1. 機率是兩極的,不是均勻散開的:中間地帶(0.2 到 0.8 之間)非常空,憑證組只有 8%(6 筆),邏輯組也只有 14%(9 筆)。絕大多數數據不是貼在 0.0-0.1,就是擠在 0.9-1.0。
  2. 它適合切門檻,但不適合用來排序:因為數據高度重疊在極端值(例如憑證組的 0.02 上就疊了 25 筆)。你如果想「把升級佇列照機率由高到低排,人從上面看下來」,排出來的順序其實跟沒排一樣。要排序,必須另外找別的訊號(例如改了什麼檔、動了幾行),不要硬用機率當排序鍵。

今天的成果,你可以直接拿去用:資料衛生紀律

從這兩組數據的加註過程中,我踩到了一個非常隱蔽的「資料衛生」陷阱。這是我這六天來第五次踩到同一個病,我把它總結成一條紀律:查不到就寫 null,不要寫 0

在設計稽核紀錄時,對於模型的加註,我們必須嚴格區分三種狀態:

rec["jev"] = None          # 狀態一:沒問過(例如確定性層已經有答案,不需升級)
rec["jev"] = {"prob": 0.03, "model": "jev-1.13.0"}   # 狀態二:問了,模型說沒事
rec["jev"] = {"prob": None, "error": "timeout"}      # 狀態三:問了,但呼叫失敗或超時

如果你偷懶,把狀態三(呼叫失敗)也寫成 prob: 0,它在報表上會被讀成「問過了,確定沒事」,進而把你之後算的每一個平均值都往下拉,而且全程不會有任何紅燈或錯誤訊息

資料衛生做好了,我們才能談下一步:這兩組實驗的數據,到底揭示了模型什麼樣的本質?


誠實欄

  • 75 筆憑證數據不是 75 個獨立樣本。 preToolUse 有 36 筆、postToolUse 有 35 筆,同一次工具呼叫的 pre 和 post 被算成了兩筆。15 個正例裡有 7 對是成對出現的,所以底層大約只有 8 個不同的事件。
  • 64 筆邏輯數據的正負例極度不平衡:61 比 3。 這意味著負例的樣本數極少,我們在評估「誤報」時必須非常小心,不能輕易外推。
  • 這不是評測集。 樣本來自單一專案的真實改動,沒有設計過的正負例配比。真要下結論得另外做。
  • jev-latest 是會動的別名。 今天這些數字是 jev-1.13.0 跑的。過幾週重跑對不上,不代表哪邊做錯。

明天,我們來看第一組實驗(憑證偵測)。我們會用真實數據看看:面對那些傳統 Regex 規則完全全盲的憑證洩漏,模型到底是如何把它們一筆一筆抓出來的?


今天對應的威脅: T3(藉 Agent 之手規避控制)。規避之所以划算,前提是事後舉不出證。今天我們釐清了「證據」的層次,定下了不容妥協的資料衛生紀律。

實驗與程式: 2026-09-19 跑、2026-09-20 重算。原始數據 data/day06-jev-secret.json(75 筆)、data/day06-jev-vs-ast.json(64 筆)。模型為 jev-1.13.0。本篇沒有引用外部來源。


上一篇
我把被改回去的那五版全找回來了:從寫檔紀錄重建版本鏈
下一篇
憑證偵測實驗:模型抓到了 Regex 漏掉的六筆
系列文
一個 Agent 我查不動,一個我改得動:內部威脅偵測的 30 天9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言